/**
 * Created by zhoumingrui on 2017/2/4.
 */
'use strict';
const POSCOEFFICIENT = Math.pow(2, 32);
class NavMeshAlgorithm {

    static getInstance() {
        if (!NavMeshAlgorithm.instance) {
            NavMeshAlgorithm.instance = new NavMeshAlgorithm();
        }
        return NavMeshAlgorithm.instance;
    }

    convertPosToLat(iYPos) {
        return (iYPos / POSCOEFFICIENT) * 360.0;
    }

    convertPosToLon(iXPos) {
        return (iXPos / POSCOEFFICIENT) * 360.0;
    }

    calLevelByMesh(iMesh) {
        let iLevel = 0;
        let iTMesh = parseInt(iMesh);

        while (true) {
            if (iTMesh / 2 === 0) {
                break;
            }
            iTMesh /= 2;
            iTMesh = parseInt(iTMesh);
            iLevel++;
        }

        iLevel = iLevel - 16;

        if (iLevel < 0) {
            return 0;
        }

        return iLevel;// / 2 + 1;
    }

    calRectPosByMesh(iMesh, nLevel) {
        let cRectPos = {};
        /*UINT64*/
        let iCodeNum = iMesh - (1 << (16 + nLevel));

        let iMinx = 0;
        let iMinY = 0;

        for (let i = 0; i < nLevel; i++) {
            if (iCodeNum & (1 << (i * 2))) {
                iMinx = iMinx | (1 << i);
            }

            if (iCodeNum & (1 << (i * 2 + 1))) {
                iMinY = iMinY | (1 << i);
            }
        }

        if (iCodeNum & (1 << (2 * nLevel))) {
            iMinx = iMinx | (1 << nLevel);
        }

        iMinx = iMinx << (32 - (nLevel + 1));
        iMinY = iMinY << (32 - (nLevel + 1));

        if (iMinY & (1 << 30)) {
            iMinY = iMinY | (1 << 31);
        }

        cRectPos.iLBX = iMinx;
        cRectPos.iLBY = iMinY;
        cRectPos.iRTX = iMinx + (1 << (32 - (nLevel + 1)));
        cRectPos.iRTY = iMinY + (1 << (32 - (nLevel + 1)));

        return cRectPos;
    }
}

module.exports = NavMeshAlgorithm;